package com.rad.datastat.utils;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.util.Log;

/**
 * 类说明：
 * 
 * @author xinhui.cheng
 * @date 2014-12-10
 * @version 1.0
 */

public final class ApplicationUtil {

	private static final String TAG = "ApplicationUtil";

	/**
	 * 获取安装的APP列表，不包含自身
	 * 
	 * @param context
	 * @param systemApp
	 * @param enable
	 * @return
	 */
	/*
	 * public static ArrayList<UninstallAppInfo> getApps(Context context,
	 * boolean systemApp, boolean enable) { ArrayList<UninstallAppInfo> list =
	 * new ArrayList<UninstallAppInfo>();
	 * 
	 * ArrayList<ApplicationInfo> infoList = getAppList(context, systemApp,
	 * enable); for (ApplicationInfo applicationInfo : infoList) {
	 * UninstallAppInfo info = new UninstallAppInfo();
	 * info.setAppPackage(applicationInfo.packageName); File file = new
	 * File(applicationInfo.sourceDir); long fileSize = file.length(); double
	 * size = (double) fileSize / (double) (1024 * 1024); info.setAppSize(size);
	 * info.setInfo(applicationInfo); list.add(info); } return list; }
	 */

	/**
	 * 获取安装的APP列表，该方法会过滤自身和应用市场
	 * 
	 * @param context
	 * @param systemApp
	 * @param enable
	 * @return
	 */
	public static ArrayList<ApplicationInfo> getAppList(Context context, boolean systemApp,
			boolean enable) {
		HashSet<String> filterPkg = new HashSet<String>();
		filterPkg.add(context.getPackageName());
		return getAppList(context, systemApp, enable, filterPkg);
	}

	/**
	 * 获取安装的APP列表
	 * 
	 * @param context
	 * @param systemApp
	 * @param enable
	 * @param filterPkg
	 *            需要过滤的应用包名，如果为null则返回所有
	 * @return
	 */
	public static ArrayList<ApplicationInfo> getAppList(Context context, boolean systemApp,
			boolean enable, Set<String> filterPkg) {
		List<PackageInfo> pi = null;
		try {
			PackageManager pm = context.getPackageManager();
			pi = pm.getInstalledPackages(0);
		} catch (Exception e) {
			e.printStackTrace();
		}
		ArrayList<ApplicationInfo> list = new ArrayList<ApplicationInfo>();

		if (pi == null) {
			return list;
		}
		for (PackageInfo p : pi) {
			if ((((p.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 1) == systemApp)
					&& (p.applicationInfo.enabled == enable)) {
				if (filterPkg != null && filterPkg.contains(p.packageName)) {
					continue;
				}
				list.add(p.applicationInfo);
			}
		}
		return list;
	}

	public static ApplicationInfo getApplicationInfo(Context context, String pkgName)
			throws NameNotFoundException {
		PackageManager pm = context.getPackageManager();
		return pm.getApplicationInfo(pkgName, 0);
	}

	public static String getAppName(Context context, ApplicationInfo info) {
		PackageManager pm = context.getPackageManager();
		return (String) pm.getApplicationLabel(info);
	}

	/*
	 * public static List<AppMd5> getUserAppData(Context context) { List<AppMd5>
	 * appMd5s = new ArrayList<AppMd5>(); List<ApplicationInfo> list =
	 * ApplicationUtil.getAppList(context, false, true, null); PackageManager pm
	 * = context.getPackageManager(); AppMd5 appMd5; for (ApplicationInfo ai :
	 * list) { appMd5 = new AppMd5(); appMd5.setPkgName(ai.packageName);
	 * appMd5.setMd5(ApplicationUtil.getFileMD5(ai.publicSourceDir));
	 * appMd5.setAppName((String) pm.getApplicationLabel(ai));
	 * appMd5s.add(appMd5); } return appMd5s; }
	 */

	public static String getFileMD5(String filePath) {
		try {
			InputStream fis = new FileInputStream(filePath);
			byte[] buffer = new byte[1024 * 100];
			MessageDigest md5 = MessageDigest.getInstance("Md5");
			int numRead = 0;
			while ((numRead = fis.read(buffer)) > 0) {
				md5.update(buffer, 0, numRead);
			}
			fis.close();
			return toHexString(md5.digest());
		} catch (IOException ex) {
			Log.d(TAG, "IOException", ex);
		} catch (NoSuchAlgorithmException e) {
			Log.d(TAG, "NoSuchAlgorithmException", e);
		}
		return null;
	}

	private static String toHexString(byte[] b) {
		char[] hexChar = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd',
				'e', 'f' };

		StringBuilder sb = new StringBuilder(b.length * 2);
		for (int i = 0; i < b.length; i++) {
			sb.append(hexChar[(b[i] & 0xf0) >>> 4]);
			sb.append(hexChar[b[i] & 0x0f]);
		}
		return sb.toString();
	}

	public static boolean isAviliable(Context context, String pkgName) {
		if (pkgName == null || "".equals(pkgName))
			return false;
		try {
			context.getPackageManager().getApplicationInfo(pkgName,
					PackageManager.GET_UNINSTALLED_PACKAGES);
			return true;
		} catch (NameNotFoundException e) {
			return false;
		}
	}
}
